package com.ggmc;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;

import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.data.extensions.Email;
import java.awt.SystemColor;

public class DetailPanel extends JPanel {
	private static final long serialVersionUID = 1L;

	//gdata gmail custom class from com.contacts, FetchContacts Method
	final Contacts myContact = new Contacts();

	private EventListenerList listenerList = new EventListenerList();

	SwingWorker<Void, Integer> mailWorker;

	JButton btnAttachMail = new JButton("Att. Mail");
	JButton btnAttachDoc = new JButton("Att. Doc");
	JButton btnContactSort = new JButton("Sort");
	JButton btnSendMail = new JButton("Send");
	JButton btnCancelMail = new JButton("Cancel");
	JButton btnExitApp = new JButton("Exit");

	private final JTextField txtUser = new JTextField(10);
	private final JPasswordField txtPass = new JPasswordField(10);
	private final JTextField txtStatus = new JTextField(10);
	private final JTextField txtSubject = new JTextField("Glitz & Glam");
	
	public String sAttachedDoc;
	public String sAttachedMail;	
	public String htmlFile;
	private final JLabel lblGmailDetails = new JLabel("Gmail Settings");
	private final JLabel lblSubject = new JLabel("Subject");
	private final JTextField txtMailTest = new JTextField("shaun.paardenkooper@gmail.com");
	private final JCheckBox chckbxMailTest = new JCheckBox("mail test");
	private final JSeparator separator = new JSeparator();
	private final JSeparator separator_1 = new JSeparator();
	private final JSeparator separator_2 = new JSeparator();

	public boolean bTestSelected = true;
	private final JSeparator separator_3 = new JSeparator();
	private final JLabel lblMail = new JLabel("Mail");
	private final JSeparator separator_4 = new JSeparator();
	
	public DetailPanel() {
		setBackground(new Color(255, 240, 245));
		txtMailTest.setFont(new Font("Tahoma", Font.PLAIN, 13));
		txtMailTest.setColumns(10);
		txtSubject.setFont(new Font("Tahoma", Font.PLAIN, 12));
		txtSubject.setColumns(10);
		
		txtUser.setText("ricky.glitzglam@gmail.com");
		txtPass.setText("tinkydomino");
		
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{100, 100, 100};
		gridBagLayout.rowHeights = new int[]{0, 0, 0, 30, 30, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{1.0, 1.0, 0.0};
		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
		setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray),"Details"));
		
		GridBagConstraints gbc_separator_4 = new GridBagConstraints();
		gbc_separator_4.gridwidth = 3;
		gbc_separator_4.fill = GridBagConstraints.BOTH;
		gbc_separator_4.insets = new Insets(0, 0, 5, 1);
		gbc_separator_4.gridx = 0;
		gbc_separator_4.gridy = 0;
		separator_4.setForeground(new Color(119, 136, 153));
		add(separator_4, gbc_separator_4);

		GridBagConstraints gbc_lblGmailDetails = new GridBagConstraints();
		gbc_lblGmailDetails.insets = new Insets(0, 0, 5, 5);
		gbc_lblGmailDetails.gridx = 1;
		gbc_lblGmailDetails.gridy = 1;
		lblGmailDetails.setForeground(SystemColor.textHighlight);
		lblGmailDetails.setFont(new Font("Tahoma", Font.BOLD, 13));
		add(lblGmailDetails, gbc_lblGmailDetails);
		
		GridBagConstraints sepGmail = new GridBagConstraints();
		sepGmail.gridwidth = 3;
		sepGmail.fill = GridBagConstraints.BOTH;
		sepGmail.insets = new Insets(0, 0, 5, 0);
		sepGmail.gridx = 0;
		sepGmail.gridy = 2;
		separator.setForeground(new Color(119, 136, 153));
		add(separator, sepGmail);
		
		JLabel lblUser = new JLabel("user:");
		lblUser.setFont(new Font("Tahoma", Font.PLAIN, 13));
		GridBagConstraints gbc_lblUser = new GridBagConstraints();
		gbc_lblUser.insets = new Insets(0, 0, 5, 5);
		gbc_lblUser.anchor = GridBagConstraints.EAST;
		gbc_lblUser.gridx = 0;
		gbc_lblUser.gridy = 3;
		add(lblUser, gbc_lblUser);
		
		GridBagConstraints gbc_txtUser = new GridBagConstraints();
		gbc_txtUser.anchor = GridBagConstraints.SOUTH;
		gbc_txtUser.gridwidth = 2;
		gbc_txtUser.insets = new Insets(0, 0, 5, 0);
		gbc_txtUser.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtUser.gridx = 1;
		gbc_txtUser.gridy = 3;
		add(txtUser, gbc_txtUser);
		txtUser.setColumns(10);
		
		JLabel lblPass = new JLabel("pass:");
		lblPass.setFont(new Font("Tahoma", Font.PLAIN, 13));
		GridBagConstraints gbc_lblPass = new GridBagConstraints();
		gbc_lblPass.insets = new Insets(0, 0, 5, 5);
		gbc_lblPass.anchor = GridBagConstraints.EAST;
		gbc_lblPass.gridx = 0;
		gbc_lblPass.gridy = 4;
		add(lblPass, gbc_lblPass);
		
		GridBagConstraints gbc_txtPass = new GridBagConstraints();
		gbc_txtPass.anchor = GridBagConstraints.SOUTH;
		gbc_txtPass.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtPass.gridwidth = 2;
		gbc_txtPass.insets = new Insets(0, 0, 5, 0);
		gbc_txtPass.gridx = 1;
		gbc_txtPass.gridy = 4;
		add(txtPass, gbc_txtPass);
		
		GridBagConstraints sepMail = new GridBagConstraints();
		sepMail.fill = GridBagConstraints.BOTH;
		sepMail.gridwidth = 3;
		sepMail.insets = new Insets(0, 0, 5, 1);
		sepMail.gridx = 0;
		sepMail.gridy = 5;
		separator_1.setForeground(new Color(119, 136, 153));
		add(separator_1, sepMail);
		
		GridBagConstraints gbc_lblMail = new GridBagConstraints();
		gbc_lblMail.insets = new Insets(0, 0, 5, 5);
		gbc_lblMail.gridx = 1;
		gbc_lblMail.gridy = 6;
		lblMail.setForeground(new Color(30, 144, 255));
		lblMail.setFont(new Font("Tahoma", Font.BOLD, 13));
		add(lblMail, gbc_lblMail);
		
		GridBagConstraints gbc_separator_3 = new GridBagConstraints();
		gbc_separator_3.gridwidth = 3;
		gbc_separator_3.fill = GridBagConstraints.BOTH;
		gbc_separator_3.insets = new Insets(0, 0, 5, 0);
		gbc_separator_3.gridx = 0;
		gbc_separator_3.gridy = 7;
		separator_3.setForeground(new Color(119, 136, 153));
		add(separator_3, gbc_separator_3);
		
		btnAttachMail.setToolTipText("attach the email campaign (html file)");
		btnAttachMail.setFont(new Font("Tahoma", Font.PLAIN, 12));
		GridBagConstraints gbc_btnAttachMail = new GridBagConstraints();
		gbc_btnAttachMail.fill = GridBagConstraints.BOTH;
		gbc_btnAttachMail.insets = new Insets(0, 0, 5, 5);
		gbc_btnAttachMail.gridx = 0;
		gbc_btnAttachMail.gridy = 8;
		add(btnAttachMail, gbc_btnAttachMail);
		
		btnAttachDoc.setFont(new Font("Tahoma", Font.PLAIN, 12));
		btnAttachDoc.setToolTipText("attach the document to mail");
		GridBagConstraints gbc_btnAttachDoc = new GridBagConstraints();
		gbc_btnAttachDoc.fill = GridBagConstraints.BOTH;
		gbc_btnAttachDoc.insets = new Insets(0, 0, 5, 5);
		gbc_btnAttachDoc.gridx = 1;
		gbc_btnAttachDoc.gridy = 8;
		add(btnAttachDoc, gbc_btnAttachDoc);
		
		btnContactSort.setFont(new Font("Tahoma", Font.PLAIN, 12));
		btnContactSort.setToolTipText("sort email contacts from *.csv file");
		GridBagConstraints gbc_btnContactSort = new GridBagConstraints();
		gbc_btnContactSort.insets = new Insets(0, 0, 5, 1);
		gbc_btnContactSort.fill = GridBagConstraints.BOTH;
		gbc_btnContactSort.gridx = 2;
		gbc_btnContactSort.gridy = 8;
		add(btnContactSort, gbc_btnContactSort);
		
		GridBagConstraints gbc_lblSubject = new GridBagConstraints();
		gbc_lblSubject.insets = new Insets(0, 0, 5, 5);
		gbc_lblSubject.anchor = GridBagConstraints.EAST;
		gbc_lblSubject.gridx = 0;
		gbc_lblSubject.gridy = 9;
		lblSubject.setFont(new Font("Tahoma", Font.PLAIN, 13));
		add(lblSubject, gbc_lblSubject);
		
		GridBagConstraints gbc_txtSubject = new GridBagConstraints();
		gbc_txtSubject.gridwidth = 2;
		gbc_txtSubject.insets = new Insets(0, 0, 5, 0);
		gbc_txtSubject.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtSubject.gridx = 1;
		gbc_txtSubject.gridy = 9;
		add(txtSubject, gbc_txtSubject);
		
		GridBagConstraints gbc_chckbxMailTest = new GridBagConstraints();
		gbc_chckbxMailTest.anchor = GridBagConstraints.EAST;
		gbc_chckbxMailTest.insets = new Insets(0, 0, 5, 5);
		gbc_chckbxMailTest.gridx = 0;
		gbc_chckbxMailTest.gridy = 10;
		chckbxMailTest.setFont(new Font("Tahoma", Font.PLAIN, 12));
		chckbxMailTest.setVerticalAlignment(SwingConstants.BOTTOM);
		chckbxMailTest.setHorizontalAlignment(SwingConstants.TRAILING);
		chckbxMailTest.setSelected(true);
		add(chckbxMailTest, gbc_chckbxMailTest);
		
		GridBagConstraints gbc_txtMailTest = new GridBagConstraints();
		gbc_txtMailTest.gridwidth = 2;
		gbc_txtMailTest.insets = new Insets(0, 0, 5, 0);
		gbc_txtMailTest.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtMailTest.gridx = 1;
		gbc_txtMailTest.gridy = 10;
		add(txtMailTest, gbc_txtMailTest);
		
		btnSendMail.setToolTipText("send email to gmail contacts");
		btnSendMail.setFont(new Font("Tahoma", Font.PLAIN, 13));
		GridBagConstraints gbc_btnSendMail = new GridBagConstraints();
		gbc_btnSendMail.fill = GridBagConstraints.BOTH;
		gbc_btnSendMail.insets = new Insets(0, 0, 5, 5);
		gbc_btnSendMail.gridx = 0;
		gbc_btnSendMail.gridy = 11;
		add(btnSendMail, gbc_btnSendMail);
		
		btnCancelMail.setFont(new Font("Tahoma", Font.PLAIN, 13));
		GridBagConstraints gbc_btnCancelMail = new GridBagConstraints();
		gbc_btnCancelMail.insets = new Insets(0, 0, 5, 1);
		gbc_btnCancelMail.fill = GridBagConstraints.BOTH;
		gbc_btnCancelMail.gridx = 2;
		gbc_btnCancelMail.gridy = 11;
		add(btnCancelMail, gbc_btnCancelMail);
		
		GridBagConstraints gbc_separator_2 = new GridBagConstraints();
		gbc_separator_2.gridwidth = 3;
		gbc_separator_2.fill = GridBagConstraints.BOTH;
		gbc_separator_2.insets = new Insets(0, 0, 5, 1);
		gbc_separator_2.gridx = 0;
		gbc_separator_2.gridy = 12;
		separator_2.setForeground(new Color(119, 136, 153));
		add(separator_2, gbc_separator_2);
		
		btnExitApp.setFont(new Font("Tahoma", Font.BOLD, 13));
		GridBagConstraints gbc_btnExitApp = new GridBagConstraints();
		gbc_btnExitApp.anchor = GridBagConstraints.SOUTH;
		gbc_btnExitApp.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnExitApp.gridwidth = 3;
		gbc_btnExitApp.insets = new Insets(0, 0, 5, 0);
		gbc_btnExitApp.gridx = 0;
		gbc_btnExitApp.gridy = 14;
		add(btnExitApp, gbc_btnExitApp);
		

		txtStatus.setText("status");
		txtStatus.setEditable(false);
		GridBagConstraints gbc_txtStatus = new GridBagConstraints();
		gbc_txtStatus.gridwidth = 3;
		gbc_txtStatus.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtStatus.gridx = 0;
		gbc_txtStatus.gridy = 15;
		add(txtStatus, gbc_txtStatus);
		txtStatus.setColumns(10);
		
		/// buttons
        btnSendMail.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
	            	if(sAttachedMail != null)	{
	            		startMail();
	            	}
	            	else {
	            		//custom title, error icon
	            		JOptionPane.showMessageDialog(DetailPanel.this,"You have not attached your html mail file","Information",JOptionPane.ERROR_MESSAGE);
	            	}
            		
            	}
        	}
        );

        btnCancelMail.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            	endMail();
        		}
        	}
        );
       
        btnExitApp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            	exitApp();
            	}
        	}
        );        

        btnAttachMail.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		sAttachedMail = attachFile();
        		}
        	}
        );

        btnAttachDoc.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		sAttachedDoc = attachFile();
        		}
        	}
        );

        btnContactSort.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		contactSort();
        		}
        	}
        );

        // Define ChangeListener
        chckbxMailTest.addChangeListener(new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            AbstractButton abstractButton = (AbstractButton)e.getSource();
            ButtonModel buttonModel = abstractButton.getModel();
            bTestSelected = buttonModel.isSelected();
          	}
          }
        );
	}
	
    public void fireDetailEvent(DetailEvent event) {
        Object[] listeners = listenerList.getListenerList();
         
        for(int i=0; i < listeners.length; i += 2) {
            if(listeners[i] == DetailListener.class) {
                ((DetailListener)listeners[i+1]).detailEventOccurred(event);
            }
        }
    }
	
    public void addDetailListener(DetailListener listener) {
        listenerList.add(DetailListener.class, listener);
    }
 
    public void removeDetailListener(DetailListener listener) {
        listenerList.remove(DetailListener.class, listener);
    }	
	
	
	private void startMail() {
		
	mailWorker = new SwingWorker<Void, Integer>() {
		
		private int i = 0;
		
		@Override
		protected Void doInBackground() throws Exception {
				
			//mail variable decl.
			String smtpHost = "mail.glitzglam.co.za";
			String from 	= "ricky@glitzglam.co.za";
			String htmlFile = sAttachedMail;
			String smtpUser = "ricky@glitzglam.co.za";
			String smtpPass = "Tinky1@";	

			//access google and fetch contacts
			String passText = new String(txtPass.getPassword());
			ContactFeed resultFeed = myContact.FetchContacts(txtUser.getText(), passText);
			
	        List<ContactEntry> entries = resultFeed.getEntries();
	        
	        Sendmail sender = new Sendmail();
	        if (bTestSelected == false) {
	        	fireDetailEvent(new DetailEvent(this, String.valueOf((entries.size()))));

	        	while (resultFeed.getEntries().size() != 0) {
	        	    resultFeed.setStartIndex(startIndex);

	        	    // Execute the query and get the response
	        	    resultFeed = service.query(myQuery, CalendarEventFeed.class);

//	        	    entriesReturned = resultFeed.getEntries().size();
//	        	    if (entriesReturned == 0)
//	        	        // We've hit the end of the list
//	        	        break;

	        	    // Add the returned entries to our local list
	        	    allCalEntries.addAll(resultFeed.getEntries());

	        	    startIndex = startIndex + entriesReturned;
	        	}
	        	
	        	while (i<entries.size() && !Thread.currentThread().isInterrupted()) {
		        	ContactEntry entry = entries.get(i);
		        	  for (Email email : entry.getEmailAddresses()) {
		        		  //send email contact text back to MainFrame (txtpnContacts) using event
		        		  fireDetailEvent(new DetailEvent(this, email.getAddress()));
		        		  //sender.mail(smtpHost, smtpUser, smtpPass, email.getAddress(), from, txtSubject.getText(), htmlFile, sAttachedDoc);	
		        	  }
					  i++;
	        	}
	        }
	        else {
      		  fireDetailEvent(new DetailEvent(this, txtMailTest.getText()));
      		  //sender.mail(smtpHost, smtpUser, smtpPass, txtMailTest.getText(), from, txtSubject.getText(), htmlFile, sAttachedDoc);	
	        }
	        	
			return null;
	}

        @Override
        // This is called when the thread finishes.
        // Can safely update GUI here.
        protected void done() {

        	btnSendMail.setEnabled(true);
    		btnCancelMail.setEnabled(false);

        	if (isCancelled())
                System.out.println("Cancelled !");
              else
                System.out.println("Done !");

        	}
	
		};
		
	mailWorker.execute();
	btnSendMail.setEnabled(false);
	btnCancelMail.setEnabled(true);
	}
	
	private void endMail() {

		if (mailWorker != null) {
			mailWorker.cancel(true);
			mailWorker = null;
		}
	}

	private void exitApp() {
		System.exit(0);
	}
	
	private String attachFile() {

	 String sfileName = null;
	  
	  JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
      int option = chooser.showOpenDialog(DetailPanel.this);
      if(option == JFileChooser.APPROVE_OPTION) {
    	  txtStatus.setText("You chose "+((chooser.getSelectedFile()!=null)? chooser.getSelectedFile().getAbsoluteFile():"nothing"));
    	  sfileName = chooser.getSelectedFile().getAbsoluteFile().toString();
      }
      if(option == JFileChooser.CANCEL_OPTION) {
    	  txtStatus.setText("You canceled.");
       }
	  return sfileName;
	}
	
	private void contactSort()	{
		
		String contactsOpen;
		String contactsSorted;
		String line = null;
        String regex1 = "<(.+?)>";
        
		boolean bHeaderOnce = true;
		
		contactsOpen = attachFile();

		if (contactsOpen != null) {
			contactsSorted = contactsOpen.substring(0, contactsOpen.length() - 4) + ".sorted.csv";
		try {
			FileReader fr = new FileReader(contactsOpen);
			final BufferedReader br = new BufferedReader(fr);
			FileWriter fw = new FileWriter(contactsSorted);
			final BufferedWriter bw = new BufferedWriter(fw);


			while ((line=br.readLine())!=null) {
                Pattern p1 = Pattern.compile(regex1);
                Matcher matcher1 = p1.matcher(line);

                try {
					///header
	        		  	if (bHeaderOnce == true) {
	        		  	bw.write("Name,E-mail 1 - Value" + System.getProperty("line.separator"));
	        		  	bHeaderOnce = false;
	        		  	}                        	
	        		  	///validate email
	        		  	new InternetAddress(line).validate();
	        		  	System.out.println(line);
	        		  	fireDetailEvent(new DetailEvent(this, line));

	        		  	///write email to file, using google csv format
	        		  	bw.write(line + "," + line + System.getProperty("line.separator"));
	        		  	
                } catch (AddressException ex) {
                    System.out.println("Error : " + ex.getMessage());
                                		
            	while (matcher1.find()) {
            		System.out.println(matcher1.group(1));
	        		  	fireDetailEvent(new DetailEvent(this, matcher1.group(1)));

	        		  	///write email to file, using google csv format
	        		  	bw.write(matcher1.group(1) + "," + matcher1.group(1) + System.getProperty("line.separator"));
            	}
			}
        	}	
				br.close();
				bw.close();
        }
        catch (IllegalStateException ex1) {
        	System.out.println("nothing found!");
        }                	
        catch (FileNotFoundException ex2) {
        	System.out.println("file not found!");
		} 
        catch (IOException ex3) {
			ex3.printStackTrace();
		}
		}
	}	


	
}
